//题目:
// 给定一个长度为 n 的整数数组 nums 。
// 假设 arrk 是数组 nums 顺时针旋转 k 个位置后的数组，我们定义 nums 的 旋转函数  F 为：
// F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]
// 返回 F(0), F(1), ..., F(n-1)中的最大值 。
// 生成的测试用例让答案符合 32 位 整数。

// 示例 1:
// 输入: nums = [4,3,2,6]
// 输出: 26
// 解释:
// F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
// F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
// F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
// F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
// 所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。

// 示例 2:
// 输入: nums = [100]
// 输出: 0
 
// 提示:
// n == nums.length
// 1 <= n <= 105
// -100 <= nums[i] <= 100
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
//代码
class Solution 
{
public:
    int maxRotateFunction(vector<int>& nums) 
    {
        //法一：暴搜————超时
        // int ret=INT_MIN;
        // for(int i=0;i<nums.size();i++)
        // {
        //     //旋转i圈
        //     int count=0,k=0;
        //     for(int j=0;j<nums.size();j++)
        //     {
        //         if(j+i<nums.size())
        //             count+=(j+i)*nums[j];
        //         else
        //             count+=nums[j]*k++;
        //     }
        //     ret=max(ret,count); 
        // }
        // return ret;

        //法二：动态规划
        int n=nums.size();
        //1.创建dp表————dp[i]表示：数组旋转i次中，F()的最大值
        vector<int> dp(n);
        //2.初始化
        int sum=0;
        for(int i=0;i<n;i++)  sum+=nums[i],dp[0]+=i*nums[i];
        //3.填表————动态转移方程dp[i]=dp[i-1]+sum-n*nums[n-i];
        int ret=dp[0];
        for(int i=1;i<n;i++)
            dp[i]=dp[i-1]+sum-n*nums[n-i],ret=max(ret,dp[i]);
        //4.确定返回值
        return ret;
    }
};